﻿//-----------------------------------------------------------------------
// <copyright file="GroupBox.cs" company="Noboru Project">
//      Copyright (c) Noboru Project. All rights reserved.
//
//      This source code is subject to terms and conditions of the New BSD License (BSD).
//      A copy of the license can be found in the License.html file at the root of this 
//      distribution. If you can not locate the New BSD License (BSD), please send an 
//      email to noboru_adm@live.com.
//      By using this source code in any fashion, you are agreeing to be bound by
//      the terms of the New BSD License (BSD) for Noboru.
//
//      You must not remove this notice, or any other, from this software.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Noboru.Windows.Controls
{
    /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.Class"]/*' />
    [TemplatePart(Name = "TitlePart", Type = typeof(ContentControl))]
    [TemplatePart(Name = "ContentRectangleGeometryPart", Type = typeof(RectangleGeometry))]
    [TemplatePart(Name = "TitleRectangleGeometryPart", Type = typeof(RectangleGeometry))]
    [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
    [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
    public class GroupBox : ContentControl
    {
        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.IsEnabledProperty"]/*'/>
        public static readonly new DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(GroupBox), new PropertyMetadata(true, GroupBox.IsEnabledPropertyChangedCallback));

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.TitleProperty"]/*'/>
        public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(object), typeof(GroupBox), null);

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.TitleTemplateProperty"]/*'/>
        public static readonly DependencyProperty TitleTemplateProperty = DependencyProperty.Register("TitleTemplate", typeof(DataTemplate), typeof(GroupBox), null);

        private RectangleGeometry _contentRectangleGeometryPart;
        private RectangleGeometry _titleRectangleGeometryPart;
        private ContentControl _titlePart;

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.Constructor"]/*'/>
        public GroupBox()
        {
            this.DefaultStyleKey = typeof(GroupBox);
            this.SizeChanged += new SizeChangedEventHandler(this.GroupBox_SizeChanged);
        }

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.IsEnabled"]/*'/>
        public new bool IsEnabled
        {
            get
            {
                return (bool)this.GetValue(IsEnabledProperty);
            }

            set
            {
                this.SetValue(IsEnabledProperty, value);
            }
        }

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.Title"]/*'/>
        public object Title
        {
            get
            {
                return (object)this.GetValue(TitleProperty);
            }

            set
            {
                this.SetValue(TitleProperty, value);
            }
        }

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.TitleTemplate"]/*'/>
        public DataTemplate TitleTemplate
        {
            get
            {
                return (DataTemplate)this.GetValue(TitleTemplateProperty);
            }

            set
            {
                this.SetValue(TitleTemplateProperty, value);
            }
        }

        private ContentControl TitlePart
        {
            get
            {
                return this._titlePart;
            }

            set
            {
                ContentControl oldTitlePart = this._titlePart;
                if (oldTitlePart != null)
                {
                    oldTitlePart.SizeChanged -= new SizeChangedEventHandler(this.TitlePart_SizeChanged);
                }

                this._titlePart = value;

                if (this._titlePart != null)
                {
                    this._titlePart.SizeChanged += new SizeChangedEventHandler(this.TitlePart_SizeChanged);
                }
            }
        }

        private RectangleGeometry ContentRectangleGeometryPart
        {
            get
            {
                return this._contentRectangleGeometryPart;
            }

            set
            {
                this._contentRectangleGeometryPart = value;
            }
        }

        private RectangleGeometry TitleRectangleGeometryPart
        {
            get
            {
                return this._titleRectangleGeometryPart;
            }

            set
            {
                this._titleRectangleGeometryPart = value;
            }
        }

        /// <include file='Documentation\GroupBoxDocumentation.uex' path='Members/Member[@for="GroupBox.OnApplyTemplate"]/*'/>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.ContentRectangleGeometryPart = (RectangleGeometry)GetTemplateChild("ContentRectangleGeometryPart");
            this.TitleRectangleGeometryPart = (RectangleGeometry)GetTemplateChild("TitleRectangleGeometryPart");
            this.TitlePart = (ContentControl)GetTemplateChild("TitlePart");
        }

        private static void IsEnabledPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((GroupBox)sender).OnIsEnabledPropertyChanged(e);
        }

        private void OnIsEnabledPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.IsEnabled = this.IsEnabled;

            this.ApplyCommonState(true);
        }

        private void ApplyCommonState(bool useTransitions)
        {
            if (this.IsEnabled)
            {
                VisualStateManager.GoToState(this, "Normal", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Disabled", useTransitions);
            }
        }

        private void GroupBox_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this._contentRectangleGeometryPart != null)
            {
                this._contentRectangleGeometryPart.Rect = new Rect(new Point(), e.NewSize);
            }
        }

        private void TitlePart_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if ((this._titleRectangleGeometryPart != null) && (this._titlePart != null))
            {
                this._titleRectangleGeometryPart.Rect = new Rect(new Point(this._titlePart.Margin.Left, 0), e.NewSize);
            }
        }
    }
}
